package com.mine.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.mine.common.utils.IDUtils;
import com.mine.dao.MineOrderMapper;
import com.mine.dao.MineShopFansMapper;
import com.mine.dao.MineShopInfoMapper;
import com.mine.dao.MineUserFeedbackCategoryMapper;
import com.mine.dao.MineUserFeedbackMapper;
import com.mine.dao.MineUserMapper;
import com.mine.jedis.JedisClient;
import com.mine.pojo.MineOrderExample;
import com.mine.pojo.MineShopFans;
import com.mine.pojo.MineShopInfo;
import com.mine.pojo.MineUser;
import com.mine.pojo.MineUserExample;
import com.mine.pojo.MineUserExample.Criteria;
import com.mine.pojo.MineUserFeedback;
import com.mine.pojo.MineUserFeedbackCategory;
import com.mine.pojo.MineUserFeedbackCategoryExample;
import com.mine.pojo.MsgCount;
import com.mine.result.CodeMsg;
import com.mine.result.Result;
import com.mine.vo.LoginVo;
import com.mine.vo.Register;

@Service
public class UserServiceImpl implements UserService {
	@Autowired
	private MineUserMapper userMapper;
	
	@Autowired
	private MineUserFeedbackMapper userFeedbackMapper;
	
	@Autowired
	private MineUserFeedbackCategoryMapper feedbackCategoryMapper;
	
	@Autowired
	private MineShopInfoMapper shopInfoMapper;
	
	@Autowired
	private MineShopFansMapper shopFansMapper;
	
	@Autowired
	private MineOrderMapper mineOrderMapper;
	
//	@Autowired
//	private MineUserFeedbackCategoryMapper feedbackCategoryMapper2;
	
//	@Autowired
//	private TbItemMapper itemMapper;
	@Autowired
	private JedisClient jedisClient;
	
	@Value("${USER_SESSION}")
	private String USER_SESSION;
	@Value("${SESSION_EXPIRE}")
	private Integer SESSION_EXPIRE;
	
	@Override
	public Result login(LoginVo vo) {
		
		// 先检查用户名密码是否正确
		MineUserExample example = new MineUserExample();
		com.mine.pojo.MineUserExample.Criteria criteria = example.createCriteria();
		criteria.andPhoneEqualTo(vo.getMobile());
		List<MineUser> list = userMapper.selectByExample(example);
		
		if (list ==null||list.size()==0) {
			return Result.error(CodeMsg.MOBILE_PWD_ERROR);
		}
		//校验密码是否正确
		MineUser tbUser = list.get(0);
		//md5加密后然后在进行校验
		if (!DigestUtils.md5DigestAsHex(vo.getPassword().getBytes()).equals(tbUser.getPassword())) {
			return Result.error(CodeMsg.MOBILE_PWD_ERROR);	
		}
		//生成token
		String token =UUID.randomUUID().toString().replace("-", "");
		tbUser.setPassword(null);
		
		//把用户信息存入到redis中 value就是用户信息
		jedisClient.set(USER_SESSION+":"+token, JSON.toJSONString(tbUser));
		//设置key的过期时间
		jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
		Map<String,Object> map =new HashMap<String, Object>();
		map.put("token",token);
		map.put("user", tbUser);
		return Result.success(map);
	}

	@Transactional
	@Override
	public Result register(Register vo) {

		//先检查是否已经注册
		MineUserExample example =new MineUserExample();
		com.mine.pojo.MineUserExample.Criteria criteria = example.createCriteria();
		criteria.andPhoneEqualTo(vo.getMobile());
		
		List<MineUser> list = userMapper.selectByExample(example);
		if (list!=null&&list.size()>0) {//用户已经存在
			return Result.error(CodeMsg.MOBILE_EXIST);
		}
		MineUser user = new MineUser();
		user.setPhone(vo.getMobile());
		user.setNickname("用户"+vo.getMobile());
		//密码要进行md5加密
		String md5Pass = DigestUtils.md5DigestAsHex(vo.getPassword().getBytes());
		user.setPassword(md5Pass);
		user.setCreateTime(new Date());;
		user.setUpdateTime(new Date());
		user.setStatus((byte) 1);
		//生成二维码 唯一识别码
		String qrcode =UUID.randomUUID().toString().replace("-", "");
		user.setQrCode(qrcode);
		userMapper.insertSelective(user);
		
		return Result.ok();
	}

	@Override
	public Result getUserByToken(String token) {
		String json = jedisClient.get(USER_SESSION + ":" + token);
		if (StringUtils.isBlank(json)) {
			return Result.error(400, "用户登录已经过期");
		}
		//重置Session的过期时间
		jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
		//把json转换成User对象
		MineUser tbUser = JSON.parseObject(json, MineUser.class);
		tbUser.setPassword(null);
		return Result.success(tbUser);
	}

	@Override
	public Result getItemList(int page, int rows) {

		PageHelper.startPage(page, rows);
//		TbItemExample example =new TbItemExample();
//		
//		List<TbItem> list = itemMapper.selectByExample(example);
//		PageInfo<TbItem> pageInfo = new PageInfo<>(list);
		return Result.success(null);
	}

	@Override
	public Result modifyPassword(String token, String oldPassword, String newPassword) {
		//先验证用户信息
    	MineUser user = getRedisUserByToken(token);
    	if (user==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	
    	//先校验旧密码是否正确
    	MineUser oldUser = userMapper.selectByPrimaryKey(user.getId());
    	String dbPassword = oldUser.getPassword();
    	if (!dbPassword.equals(DigestUtils.md5DigestAsHex(oldPassword.getBytes()))) {
			return Result.error("旧密码错误！");
		}
    	//密码要进行md5加密
    	String md5Pass = DigestUtils.md5DigestAsHex(newPassword.getBytes());
    	MineUser fUser = new MineUser();
    	fUser.setId(user.getId());
    	fUser.setPassword(md5Pass);

    	userMapper.updateByPrimaryKeySelective(fUser);
    	
		return Result.ok();
	}

	@Override
	public Result updateUserInfo(String token, MineUser user) {
		//先验证用户信息
    	MineUser redisUser = getRedisUserByToken(token);
    	if (redisUser==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	user.setId(redisUser.getId());
		user.setUpdateTime(new Date());
		userMapper.updateByPrimaryKeySelective(user);//更新用户信息
		//查询最新用户信息
		MineUser mineUser = userMapper.selectByPrimaryKey(redisUser.getId());
		//更新redis中的用户信息
		updateRedisUser(token, mineUser);
		
		return Result.ok();
	}

	@Override
	public MineUser getRedisUserByToken(String token) {
		String json = jedisClient.get(USER_SESSION + ":" + token);
		if (StringUtils.isBlank(json)) {
			return null;
		}
		//重置Session的过期时间
		jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
		//把json转换成User对象
		MineUser tbUser = JSON.parseObject(json, MineUser.class);
		return tbUser;
	}

	@Override
	public void updateRedisUser(String token, MineUser user) {
		//清空密码
		user.setPassword(null);
		//把用户信息存入到redis中 value就是用户信息
		jedisClient.set(USER_SESSION+":"+token, JSON.toJSONString(user));
		//设置key的过期时间
		jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
	}

	@Override
	public Result addUserFeedback(String token, MineUserFeedback userFeedback) {
		//先验证用户信息
    	MineUser redisUser = getRedisUserByToken(token);
    	if (redisUser==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	int i = userFeedbackMapper.insertSelective(userFeedback);
    	if (i>0) {
			return Result.ok();
		}
		return Result.error("操作失败！");
	}

	@Override
	public Result addUserFeedbackCategory(String token, MineUserFeedbackCategory feedbackCategory) {
		//先验证用户信息
    	MineUser redisUser = getRedisUserByToken(token);
    	if (redisUser==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	//用户类型，0-普通用户 1-商家 2-管理员
    	if (redisUser.getUserType()!=2) {
			return Result.error("只有管理员才能操作！");
		}
    	int i = feedbackCategoryMapper.insertSelective(feedbackCategory);
    	if (i>0) {
			return Result.ok();
		}
		return Result.error("操作失败！");
	}

	@Override
	public Result addUserFollowShop(String token, MineShopFans fans) {
		//先验证用户信息
    	MineUser redisUser = getRedisUserByToken(token);
    	if (redisUser==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	//查询该店铺是否存在
    	MineShopInfo shopInfo = shopInfoMapper.selectByPrimaryKey(fans.getShopId());
    	if (shopInfo==null) {
			return Result.error("该店铺不存在！");
		}
    	if (redisUser.getId().equals(shopInfo.getUserId())) {
    		return Result.error("不能自己关注自己店铺！");
		}
    	fans.setUserId(redisUser.getId());
    	fans.setCreateTime(new Date());
    	fans.setUpdateTime(new Date()); 
    	int i = shopFansMapper.insertSelective(fans);
    	if (i>0) {
			return Result.ok();
		}
		return Result.error("操作失败！");
	}

	@Override
	public Result getUserMsgCount(String token) {
		//先验证用户信息
    	MineUser redisUser = getRedisUserByToken(token);
    	if (redisUser==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	MineOrderExample userexample = new MineOrderExample();
    	com.mine.pojo.MineOrderExample.Criteria createCriteria = userexample.createCriteria();
    	createCriteria.andStatusEqualTo((byte) 1);
    	//查询待付款订单数量
    	createCriteria.andOrderStateEqualTo(1);
    	createCriteria.andUserIdEqualTo(redisUser.getId());
    	//待付款数量
		int dfkCount = mineOrderMapper.countByExample(userexample );
		MsgCount msgCount1 = new MsgCount();
		msgCount1.setType(1);
		msgCount1.setCount(dfkCount);
		//用户：1待付款 2待收货 商家：3待接单 4待发货 其他：5消息
		List<MsgCount> list = new ArrayList<>();
		list.add(msgCount1);
		//待收货数量
		/*orderStates.add(2);
			orderStates.add(3);
			orderStates.add(4);*/
		MineOrderExample dshexample = new MineOrderExample();
		com.mine.pojo.MineOrderExample.Criteria createCriteria2 = dshexample.createCriteria();
		createCriteria2.andUserIdEqualTo(redisUser.getId());
		createCriteria2.andStatusEqualTo((byte)1);
		List<Integer> values = new ArrayList<>();
		values.add(2);
		values.add(3);
		values.add(4);
		createCriteria2.andOrderStateIn(values );
		int dshCount = mineOrderMapper.countByExample(dshexample);
		MsgCount msgCount2 = new MsgCount();
		msgCount2.setType(2);
		msgCount2.setCount(dshCount);
		list.add(msgCount2);
		
		//System.out.println(dfkCount+"  "+dshCount);
		if (redisUser.getShopId()!=null) {//查询商铺待接单数量或者待发货数
			MineOrderExample shopexample = new MineOrderExample();
	    	com.mine.pojo.MineOrderExample.Criteria shopcreateCriteria = shopexample.createCriteria();
	    	shopcreateCriteria.andStatusEqualTo((byte) 1);
	    	//查询待接单订单数量
	    	shopcreateCriteria.andOrderStateEqualTo(2);
	    	shopcreateCriteria.andShopIdEqualTo(redisUser.getShopId());
	    	//待接单数量
			int shopdjdCount = mineOrderMapper.countByExample(shopexample );
			MsgCount msgCount3 = new MsgCount();
			msgCount3.setType(3);
			msgCount3.setCount(shopdjdCount);
			list.add(msgCount3);
			//待发货数量
			/*orderStates.add(2);
				orderStates.add(3);
				orderStates.add(4);*/
			MineOrderExample shopdshexample = new MineOrderExample();
			com.mine.pojo.MineOrderExample.Criteria shopcreateCriteria2 = shopdshexample.createCriteria();
			shopcreateCriteria2.andShopIdEqualTo(redisUser.getShopId());
			shopcreateCriteria2.andStatusEqualTo((byte)1);
			
			shopcreateCriteria2.andOrderStateEqualTo(3);
			int shopdfhCount = mineOrderMapper.countByExample(shopdshexample);
			MsgCount msgCount4 = new MsgCount();
			msgCount4.setType(4);
			msgCount4.setCount(shopdfhCount);
			list.add(msgCount4);
		}
		//有消息列表 展示消息列表数据 todo
		
		return Result.success(list);
	}

	/**
	 * 获取已经反馈分类
	 */
	@Override
	public Result getUserFeedbackCate() {
		MineUserFeedbackCategoryExample example = new MineUserFeedbackCategoryExample();
		com.mine.pojo.MineUserFeedbackCategoryExample.Criteria createCriteria = example.createCriteria();
		createCriteria.andStatusEqualTo((byte)1);
		List<MineUserFeedbackCategory> selectByExample = feedbackCategoryMapper.selectByExample(example );
		
		return Result.success(selectByExample);
	}

	/**
	 * 保存反馈信息
	 */
	@Override
	public Result saveUserFeedback(String token, MineUserFeedback userFeedback) {
		//先验证用户信息
    	MineUser redisUser = getRedisUserByToken(token);
    	if (redisUser==null) {
			return Result.error(CodeMsg.SESSION_ERROR);
		}
    	if (userFeedback.getPhone()==null) {//前端未传来电话 
			userFeedback.setPhone(redisUser.getPhone());
		}
    	userFeedback.setContact(redisUser.getNickname());
    	userFeedback.setUserId(redisUser.getId());
    	userFeedback.setStatus((byte)1);
    	userFeedback.setCreateTime(new Date());
    	userFeedbackMapper.insertSelective(userFeedback);
		return Result.ok();
	}
	
}
